package com.ksy.common.utils;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.hardware.Camera;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import android.util.DisplayMetrics;
import android.view.WindowManager;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Random;

/**
 * Created by Ksy.
 */

public class AndroidUtil {
    public String adb = "adb shell \"dumpsys activity activities | grep mFocusedActivity\"";
    public static final String tempFolder = "APaoPao";
    public static final String tempImageFolder = "APaoPao/tempImage";
    public static final String tempVoiceFolder = "APaoPao/tempVoice";
    public static final String tempVideoFolder = "APaoPao/tempVideo";
    public static final String voiceExt = ".amr";
    public static final String imageExt = ".jpeg";
    public static final String videoExt = ".mp4";

    public static int dip2px(float dp) {
        DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
        float px = dp * ((float) displayMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);
        return (int) px;
    }


    private static File getStorageDir(Context context) {
        File var1 = Environment.getExternalStorageDirectory();
        if (var1.exists()) {
            return var1;
        }
        return context.getFilesDir();
    }

    public static int px2dip(float px) {
        DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
        float dp = px / ((float) displayMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);
        return (int) dp;
    }

    public static void installApk(Context context, File apkFile) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setAction(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Uri uri = FileProvider.getUriForFile(context,
                    context.getPackageName() + ".fileurl", apkFile);
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(uri, context.getContentResolver().getType(uri));
        } else {
            Uri apkUri = Uri.fromFile(apkFile);
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        }
        try {
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static int getScreenWidth(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        if (wm == null) {
            return Resources.getSystem().getDisplayMetrics().widthPixels;
        }
        Point point = new Point();
        wm.getDefaultDisplay().getRealSize(point);
        return point.x;
    }

    public static int getScreenHeight(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        if (wm == null) {
            return Resources.getSystem().getDisplayMetrics().widthPixels;
        }
        Point point = new Point();
        wm.getDefaultDisplay().getRealSize(point);
        return point.x;
    }

    public static boolean isMain() {
        return Looper.getMainLooper().getThread() == Thread.currentThread();
    }

    public static void notifyMedia(Context context, File file) {
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        Uri contentUri = Uri.fromFile(file);
        mediaScanIntent.setData(contentUri);
        context.sendBroadcast(mediaScanIntent);
    }

    public static String getTempImageName() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault());
        String formatDate = dateFormat.format(new Date());
        return formatDate + "_" + getRandom() + imageExt;
    }

    public static String getTempVoiceName() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault());
        String formatDate = dateFormat.format(new Date());
        return formatDate + "_" + getRandom() + voiceExt;
    }

    public static String getTempVideoName() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault());
        String formatDate = dateFormat.format(new Date());
        return formatDate + "_" + getRandom() + videoExt;
    }

    public static File getTempFileFolder(Context context) {
        File dir = new File(getStorageDir(context), tempFolder);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        return dir;

    }

    public static File getTempVoiceFolder(Context context) {
        File dir = new File(getStorageDir(context), tempVoiceFolder);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        return dir;

    }

    public static File getTempImageFile(Context context) {
        File dir = new File(getStorageDir(context), tempImageFolder);
        File file = new File(dir, getTempImageName());
        if (!dir.exists()) {
            dir.mkdirs();
        }
        if (file.exists()) {
            file.delete();
        }
        return file;
    }

    public static File getTempVoiceFile(Context context) {
        File dir = new File(getStorageDir(context), tempVoiceFolder);
        File file = new File(dir, getTempVoiceName());
        if (!dir.exists()) {
            dir.mkdirs();
        }
        if (file.exists()) {
            file.delete();
        }
        return file;
    }

    public static File getTempVideoFile(Context context) {
        File dir = new File(getStorageDir(context), tempVideoFolder);
        File file = new File(dir, getTempVideoName());
        if (!dir.exists()) {
            dir.mkdirs();
        }
        if (file.exists()) {
            file.delete();
        }
        return file;
    }

    public static File getTempVideoFile(Context context, String fileName) {
        File dir = new File(getStorageDir(context), tempVideoFolder);
        File file = new File(dir, fileName + videoExt);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        if (file.exists()) {
            file.delete();
        }
        return file;
    }

    public static File getVideoFile(Context context, String fileName) {
        File dir = new File(getStorageDir(context), tempVideoFolder);
        File file = new File(dir, fileName + videoExt);
        return file;
    }


    public static int getRandom() {
        Random random = new Random();
        int s = random.nextInt(9999) % (9999 - 1000 + 1) + 1000;
        return s;
    }


    public static Uri getFileUri(Context context, File file) {
        Uri fileUri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            fileUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileurl", file);
        } else {
            fileUri = Uri.fromFile(file);
        }
        return fileUri;
    }

    public static void inputStream2file(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static Camera.Size getOptimalVideoSize(List<Camera.Size> supportedVideoSizes,
                                                  List<Camera.Size> previewSizes, int w, int h) {
        // Use a very small tolerance because we want an exact match.
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio = (double) w / h;

        // Supported video sizes list might be null, it means that we are allowed to use the preview
        // sizes
        List<Camera.Size> videoSizes;
        if (supportedVideoSizes != null) {
            videoSizes = supportedVideoSizes;
        } else {
            videoSizes = previewSizes;
        }
        Camera.Size optimalSize = null;

        // Start with max value and refine as we iterate over available video sizes. This is the
        // minimum difference between view and camera height.
        double minDiff = Double.MAX_VALUE;

        // Target view height
        int targetHeight = h;

        // Try to find a video size that matches aspect ratio and the target view size.
        // Iterate over all available sizes and pick the largest size that can fit in the view and
        // still maintain the aspect ratio.
        for (Camera.Size size : videoSizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                continue;
            if (Math.abs(size.height - targetHeight) < minDiff && previewSizes.contains(size)) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        // Cannot find video size that matches the aspect ratio, ignore the requirement
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Camera.Size size : videoSizes) {
                if (Math.abs(size.height - targetHeight) < minDiff && previewSizes.contains(size)) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }


    public static Camera getDefaultCameraInstance() {
        return Camera.open();
    }


    public static Camera getDefaultBackFacingCameraInstance() {
        return getDefaultCamera(Camera.CameraInfo.CAMERA_FACING_BACK);
    }


    public static Camera getDefaultFrontFacingCameraInstance() {
        return getDefaultCamera(Camera.CameraInfo.CAMERA_FACING_FRONT);
    }


    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    private static Camera getDefaultCamera(int position) {
        // Find the total number of cameras available
        int mNumberOfCameras = Camera.getNumberOfCameras();
        // Find the ID of the back-facing ("default") camera
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        for (int i = 0; i < mNumberOfCameras; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == position) {
                return Camera.open(i);

            }
        }

        return null;
    }


    //获取录音的文件
    public static Intent getAudioChooseIntent() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("audio/*");
        Intent chooser = Intent.createChooser(intent, "选择");
        return chooser;
    }

    //获取文件
    public static Intent getVideoChooseIntent() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("video/*");
        Intent chooser = Intent.createChooser(intent, "选择");
        return chooser;
    }

    //获取文件
    public static Intent getImageChooseIntent() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image/*");
        Intent chooser = Intent.createChooser(intent, "选择");
        return chooser;
    }

    //录音的intent
    public static Intent getCaptureAudioIntent() {
        Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
        Intent chooser = Intent.createChooser(intent, "选择");
        return chooser;
    }

    //拍照
    public static Intent getCaptureImageIntent(Uri uriImage) {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        }
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uriImage);
        return intent;
    }

    //录像
    public static Intent getCaptureVideoIntent(Uri uriVideo, int maxTime, long maxSize) {
        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        }
        intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, maxTime);
//        intent.putExtra("android.intent.extras.CAMERA_FACING", 1);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uriVideo);
        intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, maxSize);
        intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
        Intent chooser = Intent.createChooser(intent, "选择");
        return chooser;
    }

    //选图
    public static Intent getImagePickerIntent() {
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType("image/*");
        Intent chooser = Intent.createChooser(intent, "选择");
        return chooser;
    }

    public static void deleteTempPic() {
        File dir = new File(Environment.getExternalStorageDirectory(), tempImageFolder);
        deleteAllFiles(dir);
    }

    public static void deleteTempVideo() {
        File dir = new File(Environment.getExternalStorageDirectory(), tempVideoFolder);
        deleteAllFiles(dir);
    }

    public static void deleteFile(File file) {
        if (file == null) {
            return;
        }
        if (file.exists()) {
            file.delete();
        }
    }

    public static void deleteAllFiles(File file) {
        if (file == null) {
            return;
        }
        if (file.isFile()) {
            file.delete();
            return;
        }
        if (file.isDirectory()) {
            File[] childFile = file.listFiles();
            if (childFile == null || childFile.length == 0) {
                file.delete();
                return;
            }
            for (File f : childFile) {
                deleteAllFiles(f);
            }
            file.delete();
        }
    }

    private static long getFileSize(File file) throws Exception {
        long size = 0;
        if (file != null && file.exists() && file.isFile() && file.canRead()) {
            FileInputStream fis = new FileInputStream(file);
            size = fis.available();
        }
        return size;
    }

    private static long getFileSizes(File file) throws Exception {
        long size = 0;
        if (file == null) {
            return size;
        }
        File flist[] = file.listFiles();
        for (int i = 0; i < flist.length; i++) {
            File fileSub = flist[i];
            if (fileSub.isDirectory()) {
                size = size + getFileSizes(fileSub);
            } else {
                size = size + getFileSize(fileSub);
            }
        }
        return size;
    }

    public static String getFileOrFilesSize(File file) {
        long blockSize = 0;
        try {
            if (file.isDirectory()) {
                blockSize = getFileSizes(file);
            } else {
                blockSize = getFileSize(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return FormatFileSize(blockSize);
    }

    private static String FormatFileSize(long fileS) {
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString;
        String wrongSize = "0B";
        if (fileS == 0) {
            return wrongSize;
        }
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
        }
        return fileSizeString;
    }

    public static File getVideoThumb(Context context, String videoPath) {
        Bitmap videoThumbnail = ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Video.Thumbnails.FULL_SCREEN_KIND);
        return bitmap2File(context, videoThumbnail);
    }


    public static File getVideoThumb(Context context, String videoPath,int width, int height, int kind) {
        Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);
        bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
                ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
        return bitmap2File(context, bitmap);
    }


    public static File bitmap2File(Context context, Bitmap bitmap) {
        if (bitmap == null) {
            return null;
        }
        File tempImageFile = AndroidUtil.getTempImageFile(context);
        FileOutputStream fOut;
        try {
            fOut = new FileOutputStream(tempImageFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
            fOut.flush();
            fOut.close();
            bitmap.recycle();
            bitmap = null;
            System.gc();
        } catch (IOException e) {
            return null;
        }
        return tempImageFile;
    }
    public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.PNG, 100, output);
        if (needRecycle) {
            bmp.recycle();
        }

        byte[] result = output.toByteArray();
        try {
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }
}
